package cn.com.transfer.listener;

import cn.com.transfer.services.MsgHandlerService;
import cn.com.transfer.utils.Executor;
import cn.com.transfer.utils.IcbcInfo;
import flexjson.JSONDeserializer;
import org.nutz.ioc.Ioc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContext;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.FileChannel;
import java.util.Map;

/**
 * Created by Administrator on 2015/4/3.
 */
public class Server {
    private Logger logger = LoggerFactory.getLogger(Server.class);
    private Ioc ioc;
    IcbcServer icbcServer;
    private ServerSocket server;

    public void start() {
        //初始化参数
        ioc.get(IcbcInfo.class, "icbcInfo");
        //通讯开始
        socketService();
        Executor.execute(new ListenThread());
        //启动工行服务
        icbcServer = ioc.get(IcbcServer.class, "icbcServer");
        icbcServer.start();
    }

    private void socketService() {
        try {
            server = new ServerSocket(IcbcInfo.localPort);
            logger.info("开始监听端口{}", IcbcInfo.localPort);
        } catch (IOException e) {
            logger.error("error in method abc_start", e);
            System.exit(0);
        }
    }

    /**
     * 监听线程
     */
    private class ListenThread implements Runnable {

        public void run() {
            try {
                logger.info("监听线程已启动");

                boolean flag = true;
                while (flag) {
                    Socket client = null;
                    try {
                        client = server.accept();
                    } catch (IOException ignored) {
                    }

                    if (client == null) break;

                    Executor.execute(new ClientThread(client));
                }

                logger.info("监听线程已退出");
            } catch (Exception e) {
                logger.error("error in method run", e);
            }
        }
    }

    private class ClientThread implements Runnable {
        private Socket socket;
        private InputStream is = null;
        private OutputStream os = null;

        private ClientThread(Socket socket) {
            this.socket = socket;
        }


        public void run() {
            String host = socket.getRemoteSocketAddress().toString();
            logger.debug("{} 已连接", host);
            String encode = "utf-8";
            try {
                is = socket.getInputStream();
                os = socket.getOutputStream();

                byte[] len = new byte[4];
                is.read(len);
                byte[] body = new byte[Integer.valueOf(new String(len, encode))];
                is.read(body);
                String json = new String(body, encode);
                Map map = new JSONDeserializer<Map>().deserialize(json);
                MsgHandlerService handler = ioc.get(MsgHandlerService.class, (String) map.get("method"));
                json = handler.handler(map);
                body = json.getBytes(encode);
                len = String.format("%04d", body.length).getBytes(encode);
                os.write(len);
                os.write(body);
                os.flush();
            } catch (Exception e) {
                logger.error("error in ClientThread", e);
            } finally {
                try {
                    is.close();
                } catch (Exception e) {
                }
                try {
                    os.close();
                } catch (Exception e) {
                }
                try {
                    socket.close();
                } catch (Exception e) {
                }
                logger.info("{} 已断开", host);
            }
        }
    }

    public void stop() {
        Executor.shutdown();
        try {
            icbcServer.stop();
        } catch (Exception e) {
        }
        try {
            server.close();
        } catch (Exception e) {
        }
    }
}
